﻿using System;

namespace Coogle.Core
{
    public class ContainerCode
    {
        private const int CONTAINER_CODE_LENGHT = 11;

        private readonly string m_sign;
        private readonly int m_number;
        private readonly string m_check;

        public ContainerCode(string sign, int number, string check)
        {
            m_sign = sign;
            m_check = check;
            m_number = number;
        }

        public override bool Equals(object obj)
        {
            if (obj == null) return false;
            var cc = obj as ContainerCode;
            if (cc == null) return false;

            return (m_sign.Equals(cc.m_sign) &&
                    m_number.Equals(cc.m_number) &&
                    m_check.Equals(cc.m_check));
        }

        public override int GetHashCode()
        {
            return m_sign.GetHashCode() ^ m_number.GetHashCode() ^ m_check.GetHashCode();
        }

        public override string ToString()
        {
            return Sign + " " + Number.ToString().PadLeft(6, '0') + " " + Check;
        }

        public static ContainerCode New(string sign, int number, string check)
        {
            return new ContainerCode(sign, number, check);
        }

        public static ContainerCode Parse(string value)
        {
            if (value.Length != CONTAINER_CODE_LENGHT)
                throw new InvalidContainerCodeException("invalid container's code format");

            return new ContainerCode(value.Substring(0, 4).ToUpper(),
                                      Int32.Parse(value.Substring(4, 6)),
                                      value.Substring(10, 1));
        }

        public string Sign
        {
            get
            {
                return m_sign;
            }
        }

        public int Number
        {
            get
            {
                return m_number;
            }
        }

        public string Check
        {
            get
            {
                return m_check;
            }
        }
    }
}
